package com.arsl.client.view;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.vaadin.gwtgraphics.client.Group;
import org.vaadin.gwtgraphics.client.Image;
import org.vaadin.gwtgraphics.client.animation.Animatable;
import org.vaadin.gwtgraphics.client.shape.Circle;
import org.vaadin.gwtgraphics.client.shape.Rectangle;

import com.arsl.client.util.Utils;
import com.google.gwt.dom.client.Style.Cursor;

public class TagWidget extends Group implements Animatable {

	private static final int RESIZER_SIDE = 6;

	public static final int RESIZE_TO_NW = 0;
	public static final int RESIZE_TO_NE = 1;
	public static final int RESIZE_TO_SE = 2;
	public static final int RESIZE_TO_SW = 3;
	public static final int NO_RESIZE = -1;

	private Rectangle rect;
	private PageTagger tagger;
	private Image closeImg;
	private int tagId;
	private Rectangle[] resizers;

	/**
	 * @return the tagId
	 */
	public int getTagId() {
		return tagId;
	}

	/**
	 * @param tagId
	 *            the tagId to set
	 */
	public void setTagId(int tagId) {
		this.tagId = tagId;
	}

	public TagWidget(float x, float y, float width, float height) {
		rect = new Rectangle((int) x, (int) y, (int) width, (int) height);
		rect.setFillOpacity(0.6);
		rect.setStrokeColor("blue");
		rect.setStrokeWidth(2);
		rect.setFillColor("gray");

		this.add(rect);
	}

	/**
	 * @return the x
	 */
	public int getX() {
		return rect.getX();
	}

	/**
	 * @param x
	 *            the x to set
	 */
	public void setX(int x) {
		rect.setX(x);
		updateControlPlacements();
	}

	private void updateControlPlacements() {
		if (closeImg != null) {
			closeImg.setX(rect.getX() + rect.getWidth() - 20);
			closeImg.setY(rect.getY() + 10);
		}

		if (resizers != null) {
			updateResizer(resizers[0], rect.getX(), rect.getY(), RESIZER_SIDE,
					RESIZER_SIDE);
			updateResizer(resizers[1], rect.getX() + rect.getWidth()
					- RESIZER_SIDE, rect.getY(), RESIZER_SIDE, RESIZER_SIDE);
			updateResizer(resizers[2], rect.getX() + rect.getWidth()
					- RESIZER_SIDE, rect.getY() + rect.getHeight()
					- RESIZER_SIDE, RESIZER_SIDE, RESIZER_SIDE);
			updateResizer(resizers[3], rect.getX(),
					rect.getY() + rect.getHeight() - RESIZER_SIDE,
					RESIZER_SIDE, RESIZER_SIDE);
		}

	}

	private void updateResizer(Rectangle rect, int x, int y, int w, int h) {
		rect.setX(x);
		rect.setY(y);
		rect.setWidth(w);
		rect.setHeight(h);
	}

	/**
	 * @return the y
	 */
	public int getY() {
		return rect.getY();
	}

	/**
	 * @param y
	 *            the y to set
	 */
	public void setY(int y) {
		rect.setY(y);
		updateControlPlacements();
	}

	/**
	 * @return the width
	 */
	public int getWidth() {
		return rect.getWidth();
	}

	/**
	 * @param width
	 *            the width to set
	 */
	public void setWidth(int width) {
		rect.setWidth(width);
		updateControlPlacements();
	}

	/**
	 * @return the height
	 */
	public int getHeight() {
		return rect.getHeight();
	}

	/**
	 * @param height
	 *            the height to set
	 */
	public void setHeight(int height) {
		rect.setHeight(height);
		updateControlPlacements();
	}

	public void setPageTagger(PageTagger tagger) {
		this.tagger = tagger;
	}

	public void setControls() {
		/*
		 * String resource = "com/arsl/button_red_close.gif"; InputStream
		 * inputStream = null; try { inputStream =
		 * Resources.getResourceAsStream(resource); } catch (IOException e) { //
		 * TODO Auto-generated catch block e.printStackTrace(); }
		 */

		closeImg = new Image(rect.getX() + rect.getWidth() - 16,
				rect.getY() + 16, 16, 16,
				"http://www.omyen.com/img/button_red_close.gif");

		resizers = new Rectangle[4];
		for (int i = 0; i < 4; i++) {
			resizers[i] = new Rectangle(0, 0, 0, 0);
		}

		resizers[0].getElement().getStyle().setCursor(Cursor.NW_RESIZE);
		resizers[1].getElement().getStyle().setCursor(Cursor.NE_RESIZE);
		resizers[2].getElement().getStyle().setCursor(Cursor.SE_RESIZE);
		resizers[3].getElement().getStyle().setCursor(Cursor.SW_RESIZE);

		updateControlPlacements();
		this.add(closeImg);
		for (Rectangle rect : resizers) {
			this.add(rect);
		}
	}

	@Override
	public void setPropertyDouble(String property, double value) {
		rect.setPropertyDouble(property, value);
		updateControlPlacements();
	}

	public boolean isCloseClick(int x, int y) {
		return containsInRect(x, y, closeImg.getX(), closeImg.getY(),
				closeImg.getWidth(), closeImg.getHeight());

	}

	public boolean containsInRect(int x, int y, int rectX, int rectY,
			int rectWidth, int rectHeight) {
		int ex = rectX + rectWidth;
		int ey = rectY + rectHeight;
		return rectX <= x && x <= ex && rectY <= y && y <= ey;
	}

	public boolean contains(int x, int y) {
		return containsInRect(x, y, getX(), getY(), getWidth(), getHeight());
	}

	public int resizingDirection(int x, int y) {
		for (int i = 0; i < 4; i++) {
			if (Utils.rectContainsPoint(resizers[i], x, y)) {
				return i;
			}
		}
		return -1;
	}

	/**
	 * 
	 * @param x
	 * @param y
	 * @return whetehr the event was consumed
	 */
	public boolean clickHandlder(int x, int y) {
		if (isCloseClick(x, y)) {
			tagger.removeTag(this);
		} else {
			tagger.showContentEditPanel(this);
			return true;
		}
		return false;
	}

	public boolean overlaps(TagWidget tagWidget) {
		return containsInRect(tagWidget.getX(), tagWidget.getY(), rect)
				|| containsInRect(tagWidget.getX() + tagWidget.getWidth(),
						tagWidget.getY() + getHeight(), rect)
				|| containsInRect(tagWidget.getX() + tagWidget.getWidth(),
						tagWidget.getY(), rect)
				|| containsInRect(tagWidget.getX(), tagWidget.getY()
						+ tagWidget.getHeight(), rect);
	}

	private Rectangle getRectangle() {
		return rect;
	}

	private boolean containsInRect(int x, int y, Rectangle cRect) {
		return containsInRect(x, y, cRect.getX(), cRect.getY(),
				cRect.getWidth(), cRect.getHeight());
	}
}
